package idp

import (
	"fmt"
	"gin-sso/conf"
	"gin-sso/dal/query"
	"gin-sso/jwtx"
	"github.com/gin-gonic/gin"
	"net/http"
	"strings"
)

func loginHandler(c *gin.Context) {
	spCallbackURL := c.PostForm("sp_callback_url")
	// 验证URL合法性
	if !ValidURL(c, spCallbackURL) {
		c.String(http.StatusBadRequest, "无效的SP回调URL")
		return
	}

	if err := c.ShouldBind(&loginReq); err != nil {
		c.HTML(http.StatusBadRequest, "login.html", gin.H{"error": "用户名或密码不能为空", "spCallbackURL": spCallbackURL}) // 保持回调URL
		return
	}

	// 模拟验证用户名密码（实际应查数据库）
	//if loginReq.Username != "admin" || loginReq.Password != "123456" {
	//	c.HTML(http.StatusBadRequest, "login.html", gin.H{
	//		"error":         "用户名或密码错误",
	//		"spCallbackURL": spCallbackURL, // 保持回调URL
	//	})
	//	return
	//}

	res, err := query.User.WithContext(c).Where(query.User.Name.Eq(loginReq.Username), query.User.Password.Eq(loginReq.Password)).First()
	if err != nil {
		c.HTML(http.StatusBadRequest, "login.html", gin.H{"error": "用户名或密码错误", "spCallbackURL": spCallbackURL}) // 保持回调URL
		return
	}

	// 生成JWT
	token, err := jwtx.GenerateToken(res.ID, *res.Name)
	if err != nil {
		c.HTML(http.StatusInternalServerError, "login.html", gin.H{"error": "生成令牌失败", "spCallbackURL": spCallbackURL}) // 保持回调URL
		return
	}

	// 登录成功，跳转到SP的回调地址，并携带JWT（通过URL参数或Cookie）
	// 这里用URL参数，SP收到后会存入Cookie
	//fmt.Println("Redirect:", fmt.Sprintf("%s&token=%s", spCallbackURL, token))
	//Redirect: http://localhost:8081/callback?redirect=/user&token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxMDAxLCJ1c2VybmFtZSI6ImFkbWluIiwiaXNzIjoic3NvLWlkcCIsImV4cCI6MTc1MjcyMzUwMywiaWF0IjoxNzUyNzE2MzAzfQ.g4ZC4fY0Gey26rICfuxl6uDHD5jW4LWicUZWh4zXJaLmr1-t3Bav5OA3h4WUuP3PnzQoDFeb1MMACzt_gwKpbd92d4pXULbOfXcc9Au0aqomniZwOrkC8LU7oUEDlBDBuE6w8yZSov5yds7dKaEte8gspICxCVRNGJE6ap7VFRq6dVeqJrM3R3ftiNn_ioSLN23eOE10CeITlFBiuSmrDaQ2A-VK5x4cpFRxepcrp1KxAKvv9_pGlN7IcmjFJ7VBHtx1wRKr2upKfFeefM9ACdm9su_2ltFJJ0SH0ItXkr25rbRZP7mtMQ-3U5r28RV6o2TitpzHG-sjok2YlxJSqw
	c.Redirect(http.StatusFound, fmt.Sprintf("%s&token=%s", spCallbackURL, token))
}

func loginHTMLHandler(c *gin.Context) {
	//fmt.Println("Request:", c.Request.URL.String()) // Request: /loginHTML?sp_url=http%3A%2F%2Flocalhost%3A8081%2Fcallback%3Fredirect%3D%2Fuser
	spCallbackURL := c.Query("sp_url") // spURL: http://localhost:8081/callback?redirect=/user
	//fmt.Println("spURL:", spCallbackURL)

	if !ValidURL(c, spCallbackURL) {
		c.String(http.StatusBadRequest, "无效的SP回调URL,请联系管理员")
	}
	c.HTML(http.StatusOK, "login.html", gin.H{
		"spCallbackURL": spCallbackURL,
	})
}

// 验证SP回调URL是否合法（防止开放重定向漏洞） 验证是否在白名单
func ValidURL(c *gin.Context, spURL string) bool {
	if spURL == "" {
		//spCallbackURL = conf.GlobalConf.DefaultSpCallbackURL // 默认回调URL
		c.JSON(http.StatusOK, gin.H{
			"msg": "SP回调URL为空,请联系管理员",
		})

	}

	// 检查域名是否在白名单中
	for _, v := range conf.GlobalConf.AllowedSPDomains { // v http://localhost:8081
		if strings.HasPrefix(spURL, v) { // spURL http://localhost:8081/callback?redirect=/user
			return true
		}
	}
	return false
}
